# 容器数据类型
# chainMap
from collections import ChainMap

a = {"x": 1, "z": 3}
b = {"y": 2, "z": 4}
c = ChainMap(a, b)
print(c)  # ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
# 可直接通过访问c来访问a、b中的值,如果键重复出现，会使用第一个出现的值
print("x: {}, y: {}, z: {}".format(c["x"], c["y"], c["z"]))  # x: 1, y: 2, z: 3
c.update()
# 对象属性 maps
print('c.maps', c.maps)  # c.maps [{'x': 1, 'z': 3}, {'y': 2, 'z': 4}]
# 对于属性 parents
# 去掉前一个dict
print('c.parents', c.parents)  # c.parents ChainMap({'y': 2, 'z': 4})
print('c.parents.maps', c.parents.maps)  # c.parents.maps [{'y': 2, 'z': 4}]
print('c.parents.parents', c.parents.parents)  # c.parents.parents ChainMap({})

# 更改y的值,如果键重复出现，会更改第一个出现的值,不存在 ，则在maps属性中出现的第一组dict中加入键值对
c['y'] = 5
# c.update('z', 6)
print(c)  # ChainMap({'x': 1, 'z': 3, 'y': 5}, {'y': 2, 'z': 4})

# 只能删除maps属性中第一组dict中出现的值
print(c.pop('z'))  # 3
print(c)  # ChainMap({'x': 1, 'y': 5}, {'y': 2, 'z': 4})
# del c['z']
# 转字典
print(dict(c))  # {'z': 4, 'x': 1, 'y': 5}
# 转列表
print(list(c))  # ['z', 'x', 'y']
print(c)  # ChainMap({'x': 1, 'y': 5}, {'y': 2, 'z': 4})

d = ChainMap()
d['x'] = 1
print(d)  # ChainMap({'x': 1})

# d = e前方插入一个空dict
e = d.new_child()
print(e)  # ChainMap({}, {'x': 1})

# Counter
from collections import Counter

# 定义Counter对象
c = Counter(a=4, b=2, c=0, d=-2)
# 获取所有元素
print(sorted(c.elements()))  # ['a', 'a', 'a', 'a', 'b', 'b']
# 查看最常见出现的k个元素
print(Counter('abrarcadabra').most_common(3))  # [('a', 5), ('r', 3), ('b', 2)]
# 词频统计
colors = ['red', 'red', 'red', 'blue']
print(dict(Counter(colors)))  # {'red': 3, 'blue': 1}
# 更新
c = Counter(a=3, b=1)
d = Counter(a=1, b=2)
print('c+d:', c + d)  # c+d: Counter({'a': 4, 'b': 3})
# 相减，如果小于等于0，删去
print('c-d:', c - d)  # c-d: Counter({'a': 2})
# 求最小
print('c&d:', c & d)  # c&d: Counter({'a': 1, 'b': 1})
# 求最大
print('c|d:', c | d)  # c|d: Counter({'a': 3, 'b': 2})

# deque对象
from collections import deque

# 创建
dq = deque()
# 添加元素
dq.append(1)
dq.append(2)
dq.append(3)
# 查看队列
print(dq)
print(dq[0])
# 插入元素
dq.insert(2, 99)
print(dq)
print(dq[2])
# 搜索元素
print(dq.index((99)))
# 更新元素
dq[1] = 88
print(dq)
# 删除元素
dq.remove(88)
# 删除左侧元素
templ = dq.popleft()
# 删除右侧元素
tempr = dq.pop()
print(dq)
# 队列长度
print(len(dq))

# defaultdict 对象
from collections import defaultdict

dict1 = defaultdict(int)
dict2 = defaultdict(set)
dict3 = defaultdict(str)
dict4 = defaultdict(list)
dict1[2] = 'two'

print(dict1.__missing__(2))
print(dict1[1])
print(dict2[1])
print(dict3[1])
print(dict4[1])

# namedtuple 命名元祖的工厂函数
from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(11, 22)

# 访问元素
print(p, p.x, p.y, p[0], p[1], getattr(p, 'x'))  # Point(x=11, y=22) 11 22 11 22 11
# 创建实例
print(Point._make([1, 2]))  # Point(x='a', y='b')
# 转为Orderdict,字段名称
print(p._asdict(), p._fields)  # OrderedDict([('x', 11), ('y', 22)]) ('x', 'y')
# 返回一个新的命名元素并替换值
print(p._replace(x=44))
# 字典转换成命名元祖
d = {'x': 55, 'y': 66}
print(Point(**d))

# Orderdict 对象
from collections import OrderedDict

d1 = OrderedDict()
d1['b'] = 'b'
d1['a'] = 'a'
d1['c'] = 'c'
print(d1)  # OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c')])
dd = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}
# 按key排序
kd = OrderedDict(sorted(dd.items(), key=lambda t: t[0]))
print(kd)  # OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])
# 按照value排序
vd = OrderedDict(sorted(dd.items(), key=lambda t: t[1]))
print(vd)  # OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

# UserDict 对象
from collections import UserDict
import sys

d0 = dict(a=1, b=2)
d1 = UserDict(d0)
print(d0, d1)  # {'a': 1, 'b': 2} {'a': 1, 'b': 2}
print(sys.getsizeof(d0), sys.getsizeof(d1), sys.getsizeof(d1.data))  # 240 56 240

# collections.abc --- 容器的抽象基类 介绍了一些容器的抽象基类
